home *** CD-ROM | disk | FTP | other *** search
- /*
- * mailout.c -- functions to compose service response
- *
- * 18-Feb-93 weber@eitech.com added ENCODING field to override encoding
- * 18-Feb-93 weber@eitech.com passes SPLITSIZE to splitmail
- * 18-Feb-93 weber@eitech.com added several outgoing header lines
- * 27-Jun-92 weber@eitech.com marked ServiceMail(tm) v1.0
- * 19-Jun-92 weber@eitech.com
- *
- * Copyright (c) 1992 Enterprise Integration Technologies Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name of
- * Enterprise Integration Technologies Corporation may not be used in any
- * advertising or publicity relating to the software without the specific,
- * prior written permission of Enterprise Integration Technologies Corporation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL ENTERPRISE INTEGRATION TECHNOLOGIES CORPORATION BE
- * LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
- * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
- * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <tcl.h>
- #include <sys/time.h>
- #include <time.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <unistd.h>
-
- #include "mesh.h"
-
- #define NO_ENCODING 1
- #define QP_ENCODING 2
- #define BASE64_ENCODING 3
- #define SURVEY_SIZE 10000
- #define BLKSIZE 512
- #define MAXMIMELINELEN 75
-
- int mailout(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- FILE *serv, *popen();
- time_t time(), t;
- int splitsize = 100000, i;
- int subargc;
- char **subargv;
- char *to;
- char buf[1024], m[256];
-
- if (argc != 3) {
- interp->result = "wrong # of args to mailout proc";
- return TCL_ERROR;
- }
-
- Tcl_SplitList(interp, argv[1], &subargc, &subargv);
-
- for (i=0; i<subargc-1; i++)
- if (!strcasecmp(subargv[i], "splitsize"))
- splitsize = atoi(subargv[i+1]);
-
- #ifdef MAILER
- sprintf(m, MAILER, splitsize);
- serv = popen(m, "w");
- if (serv == NULL) {
- interp->result = "Cannot start mailer process";
- return TCL_ERROR;
- }
- #else
- serv = stdout;
- #endif
-
- while (subargc > 1) {
- if (!strcasecmp(subargv[0], "to"))
- {
- to=subargv[1];
- fprintf(serv, "To: %s\n", subargv[1]);
- }
- else if (!strcasecmp(subargv[0], "inreplyto"))
- fprintf(serv, "In-Reply-To: %s\n", subargv[1]);
- else if (!strcasecmp(subargv[0], "subject"))
- fprintf(serv, "Subject: %s\n", subargv[1]);
- else if (!strcasecmp(subargv[0], "cc"))
- fprintf(serv, "Cc: %s\n", subargv[1]);
- else if (!strcasecmp(subargv[0], "date"))
- fprintf(serv, "Date: %s\n", subargv[1]);
- else if (!strcasecmp(subargv[0], "messageid"))
- fprintf(serv, "Message-Id: %s\n", subargv[1]);
- else if (!strcasecmp(subargv[0], "from"))
- fprintf(serv, "From: %s\n", subargv[1]);
- else if (!strcasecmp(subargv[0], "splitsize"))
- fprintf(serv, "X-Splitsize: %s\n", subargv[1]);
- subargv += 2;
- subargc -= 2;
- }
- free((char *) *subargv);
- fprintf(serv, "MIME-Version: 1.0\n");
- #ifdef OUTBOX
- fprintf(serv, "Bcc: %s\n", OUTBOX);
- #endif
-
- PrintMiffBodyRep(serv, argv[2]);
-
- #ifdef MAILER
- if (pclose(serv)) {
- interp->result = "Mailer terminated with an error.";
- #ifdef FACILITY
- if(logging)
- {
- openlog("mesh",(LOG_PID | LOG_CONS),loglevel);
- syslog(loglevel | LOG_ALERT,"Mailer terminated with an error: Mail to:%s",to);
- }
- #endif
- return TCL_ERROR;
- }
- #endif
- #ifdef FACILITY
- if(logging)
- {
- openlog("mesh",(LOG_PID | LOG_CONS),loglevel);
- syslog(loglevel | LOG_INFO,"Successfully mailed to %s.",to);
- }
- #endif
- return TCL_OK;
- }
-
- PrintMiffBodyRep(serv, tclvar)
- char *tclvar;
- FILE *serv;
- {
- Tcl_Interp *interp;
-
- PrintMiffSubBodyRep(serv, tclvar, interp = Tcl_CreateInterp());
- Tcl_DeleteInterp(interp);
- }
-
- PrintMiffSubBodyRep(serv, s, interp)
- FILE *serv;
- char *s;
- Tcl_Interp *interp;
- {
- int i;
- char **argv, **argv2;
- int argc, argc2;
- char *type="text", *subtype="plain", *file=NULL, *description=NULL;
- char *id=NULL, *string="Your service request was processed.";
- char *params=NULL, *parts=NULL, encoding=0;
- char boundary[80];
- FILE *stream, *fopen();
-
- Tcl_SplitList(interp, s, &argc, &argv);
- for (i=0; i<argc; i+=2) {
- if (!strcasecmp(argv[i], "type")) type = argv[i+1];
- else if (!strcasecmp(argv[i], "subtype")) subtype = argv[i+1];
- else if (!strcasecmp(argv[i], "description")) description = argv[i+1];
- else if (!strcasecmp(argv[i], "id")) id = argv[i+1];
- else if (!strcasecmp(argv[i], "file")) file = argv[i+1];
- else if (!strcasecmp(argv[i], "string")) string = argv[i+1];
- else if (!strcasecmp(argv[i], "parts")) parts = argv[i+1];
- else if (!strcasecmp(argv[i], "params")) params = argv[i+1];
- else if (!strcasecmp(argv[i], "encoding")) {
- if (!strcasecmp(argv[i+1], "base64")) encoding = BASE64_ENCODING;
- else if (!strcasecmp(argv[i+1], "quoted-printable")) encoding = QP_ENCODING;
- else encoding = NO_ENCODING;
- }
- }
- if (id == NULL) id = file; /* id defaults to filename */
-
- if (id) fprintf(serv, "Content-Id: %s\n", id);
- if (description) fprintf(serv, "Content-Description: %s\n", description);
- fprintf(serv, "Content-Type: %s/%s", type, subtype);
- if (params && *params) {
- Tcl_SplitList(interp, params, &argc2, &argv2);
- for (i=0; i<argc2; i+=2) {
- fprintf(serv, "; %s=\"%s\"", argv2[i], argv2[i+1]);
- }
- free((char *) argv2);
- }
- else if (!strcasecmp(type, "text")) fputs("; charset=us-ascii", serv);
-
- if (!strcasecmp(type, "multipart") && parts) {
- new_boundary(boundary);
- fprintf(serv, "; boundary=\"%s\"\n\n", boundary);
- Tcl_SplitList(interp, parts, &argc2, &argv2);
- for (i=0; i<argc2; i++) {
- fprintf(serv, "\n--%s\n", boundary);
- PrintMiffSubBodyRep(serv, argv2[i], interp);
- }
- free((char *) argv2);
- fprintf(serv, "\n--%s--\n", boundary);
- }
- else {
- fputc('\n', serv);
- if (file) {
- if (stream = fopen(file, "r")) {
- switch (encoding ? encoding : needs_encoding(stream, type, subtype)) {
- case QP_ENCODING:
- fputs("Content-Transfer-Encoding: quoted-printable\n\n", serv);
- toqp(stream, serv);
- break;
- case BASE64_ENCODING:
- fputs("Content-Transfer-Encoding: base64\n\n", serv);
- to64(stream, serv);
- default:
- fputc('\n', serv);
- to7bit(stream, serv);
- break;
- }
- }
- else {
- fputs(s, stderr);
- ErrorExit("some file does not exist!");
- }
- }
- else {
- fputc('\n', serv);
- fputs(string, serv);
- fputc('\n', serv);
- }
- }
- free((char *) argv);
- }
-
- /*
- needs_encoding(FILE *f) scans the first SURVEY_SIZE bytes from f and
-
- if more than 10% of the bytes are unprintable, return BASE64_ENCODING
- else if any lines are longer than 75 characters or any bytes are
- unprintable, return QP_ENCODING
- else return NO_ENCODING
- */
-
- int needs_encoding(fp, type, subtype)
- FILE *fp;
- char *type, *subtype;
- {
- int pos = 0; /* position in file */
- int printable = 0; /* num of printable chars seen so far */
- char line[MAXMIMELINELEN+2]; /* the next line from file */
- int len; /* length of a line */
- int c; /* next char read from file */
-
- while ((pos <= SURVEY_SIZE) && ((c = getc(fp)) != EOF)) {
- if (isascii(c) && (isprint(c) || isspace(c))) printable++;
- pos++;
- }
- rewind(fp);
-
- /* Are more than 1/10 of chars unprintable? Then return BASE64_ENCODING */
- if (pos/(pos-printable+1) < 10) return BASE64_ENCODING;
- #ifdef CHECKFORNOENCODING
- /* If ANY bytes are unprintable return QP_ENCODING */
- if (printable < pos) return QP_ENCODING;
-
- /* else if any lines are longer than MAXMIMELINELEN characters,
- * then return QP_ENCODING */
-
- /* read file a line at a time */
- for (pos = 0;fgets(line,MAXMIMELINELEN+2,fp) != NULL;) {
- if (pos > SURVEY_SIZE) {
- rewind(fp);
- return NO_ENCODING;
- }
- len = strlen(line) -1;
- if (len > MAXMIMELINELEN) {
- rewind(fp);
- return QP_ENCODING;
- }
- pos += len+1; /* keep track of position in file */
- }
- rewind(fp);
- return NO_ENCODING;
- #else
- return QP_ENCODING; /* why not? NO_ENCODING is a special case of QP */
- #endif
- }
-
- to7bit(inf, outf)
- FILE *inf, *outf;
- {
- char buf[BUFSIZ];
- int items;
-
- while(items = fread(buf, sizeof(char), BUFSIZ, inf))
- fwrite(buf, sizeof(char), items, outf);
- }
-
- #define MAXHOSTNAMELEN 256
-
- new_boundary(buf)
- char *buf;
- {
- static int ctr=0;
- char hname[MAXHOSTNAMELEN];
-
- gethostname(hname, MAXHOSTNAMELEN);
- sprintf(buf, "boundary.%s.%d.%d.%d", hname, getuid(), getpid(),
- ctr++);
- }
-